using System;

namespace Fadd.Components
{
    /// <summary>
    /// This attribute can be put on a component to let the system find and load it.
    /// </summary>
    public class ComponentAttribute : Attribute
    {
    	/// <summary>
        /// Initializes a new instance of the <see cref="ComponentAttribute"/> class.
        /// </summary>
        /// <param name="interfaceType">Type of the interface used to access this component.</param>
        public ComponentAttribute(Type interfaceType)
        {
            IsPrivate = false;
            InterfaceType = interfaceType;
        }

		/// <summary>
		/// Initializes a new instance of the <see cref="ComponentAttribute"/> class.
		/// </summary>
		/// <param name="interfaceType">Type of the interface used to access this component.</param>
		/// <param name="runAt"><see cref="RunAt"/></param>
		public ComponentAttribute(Type interfaceType, string runAt)
		{
			IsPrivate = false;
			InterfaceType = interfaceType;
			RunAt = runAt;
		}


        /// <summary>
        /// Initializes a new instance of the <see cref="ComponentAttribute"/> class.
        /// </summary>
        /// <param name="interfaceType">Type of the interface used to access this component.</param>
        /// <param name="isPrivate">Component is private, and cannot therefore not be accessed from <see cref="IComponentManager"/>.</param>
        public ComponentAttribute(Type interfaceType, bool isPrivate)
        {
            IsPrivate = isPrivate;
            InterfaceType = interfaceType;
        }

		/// <summary>
		/// Initializes a new instance of the <see cref="ComponentAttribute"/> class.
		/// </summary>
		/// <param name="interfaceType">Type of the interface used to access this component.</param>
		/// <param name="isPrivate">Component is private, and cannot therefore not be accessed from <see cref="IComponentManager"/>.</param>
		/// <param name="runAt"><see cref="RunAt"/></param>
		public ComponentAttribute(Type interfaceType, bool isPrivate, string runAt)
		{
			IsPrivate = isPrivate;
			InterfaceType = interfaceType;
			RunAt = runAt;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="ComponentAttribute"/> class.
		/// </summary>
		/// <param name="interfaceType">Type of the interface used to access this component.</param>
		/// <param name="isPrivate">Component is private, and cannot therefore not be accessed from <see cref="IComponentManager"/>.</param>
		/// <param name="runAt"><see cref="RunAt"/></param>
		/// <param name="version"><see cref="Version"/></param>
		public ComponentAttribute(Type interfaceType, bool isPrivate, string runAt, int version)
		{
			IsPrivate = isPrivate;
			InterfaceType = interfaceType;
			Version = version;
			RunAt = runAt;
		}

    	/// <summary>
    	/// Gets whether component is private.
    	/// </summary>
    	/// <remarks>
    	/// Private components cannot be accessed from <see cref="IComponentManager"/>.
    	/// </remarks>
    	public bool IsPrivate { get; private set; }

    	/// <summary>
    	/// Interface type used to access the component.
    	/// </summary>
    	public Type InterfaceType { get; private set; }

    	/// <summary>
    	/// Determines where the component should be running.
    	/// </summary>
    	/// <remarks>
    	/// <para>
    	/// Is useful if you have an assembly which is included both at client side and
    	/// server side. You can specify RunAt="server" to force the component to load
    	/// only at the server.
    	/// </para>
    	/// </remarks>
    	public string RunAt { get; private set; }

    	/// <summary>
    	/// Gets or sets version number.
    	/// </summary>
    	/// <remarks>
    	/// The component loader will always instantiate the latest
    	/// implementation of an interface.
    	/// </remarks>
    	public int Version { get; set; }
    }

}
